package jmine.tec.proxy.cglib;

import net.sf.cglib.proxy.Enhancer;
import jmine.tec.proxy.AbstractProxyBuilder;
import jmine.tec.proxy.ProxyBuilder;
import jmine.tec.proxy.chain.ChainElement;

/**
 * ProxyBuilder that delegates to CGLlib to create proxies.
 * @author MarceloT
 */
public class CGLibProxyBuilder extends AbstractProxyBuilder implements ProxyBuilder {

    private final Enhancer enhancer = new Enhancer();

    private ChainElement[] elements = new ChainElement[0];

    private Object delegate;

    /**
     * @return Object
     */
    public Object build() {
        ChainedMethodInterceptor interceptor = new ChainedMethodInterceptor(delegate, elements);
        enhancer.setCallback(interceptor);
        enhancer.setInterfaces(this.collectAllInterfaces());
        return enhancer.create();
    }

    /**
     * @param elements1 the elements
     */
    public void setChainElements(ChainElement... elements1) {
        this.elements = elements1;
    }

    /**
     * @param delegate the delegate
     */
    public void setDelegate(Object delegate) {
        if (delegate != null) {
            enhancer.setSuperclass(delegate.getClass());
            addInterfacesFrom(delegate.getClass());
        }
        this.delegate = delegate;
    }

    /**
     * @return String
     */
    @Override
    public String toString() {
        return "CGLIBProxyBuilder for: " + this.delegate.getClass();
    }

    /**
     * @param type the type
     */
    @Override
    public void doSetMainType(Class<?> type) {
        this.enhancer.setSuperclass(type);
    }

}
